<template>
  <el-card style="max-width: 900px; margin: 40px auto;">
    <h2>卫星仿真配置</h2>

    <!-- 表单 -->
    <el-form label-position="left" label-width="120px">
      <!-- TLE 文件 + 时间范围 + 卫星选择 -->
      <el-row 
  :gutter="30" 
  style="align-items: center; flex-wrap: nowrap;"
>
  <!-- TLE 文件上传 -->
  <el-col :span="8">
    <div style="padding: 8px 0;">
      <input
        type="file"
        accept=".tle"
        @change="handleFileUpload"
        style="
          width: 100%;
          padding: 10px;
          border: 1px dashed #bbb;
          border-radius: 6px;
          background-color: #fafafa;
          font-size: 14px;
          color: #555;
        "
        @click="(e) => e.target.value = null"/>
    </div>
  </el-col>

  <!-- 时间范围选择 -->
  <el-col :span="10">
    <el-date-picker
      v-model="timeRange"
      type="datetimerange"
      range-separator="至"
      start-placeholder="开始时间"
      end-placeholder="结束时间"
      value-format="YYYY-MM-DD HH:mm:ss"
      @change="handleTimeRangeChange"
      size="large"
      style="width: 100%;"
      popper-class="tle-time-picker-popper"
    />
  </el-col>

  <!-- 卫星选择下拉框 -->
  <el-col :span="6">
    <el-select
      v-model="selectedSatelliteIndex"
      placeholder="请选择卫星"
      :disabled="tleLines.length === 0"
      @change="handleSatelliteChange"
      size="large"
      style="width: 100%;"
    >
      <el-option
        v-for="(sat, index) in tleLines"
        :key="index"
        :label="sat"
        :value="index+1"
      />
    </el-select>
  </el-col>
</el-row>

      <!-- 地面站配置 -->
      <h3>地面站配置</h3>
      <div
        v-for="(station, index) in groundStations"
        :key="index"
        style="margin-bottom: 15px; border: 1px solid #eee; padding: 10px;"
      >
        <el-row :gutter="10">
          <el-col :span="4">
            <el-input v-model="station.name" placeholder="名称"></el-input>
          </el-col>
          <el-col :span="6">
            <el-input-number
              v-model="station.latitude"
              :step="0.0001"
              :min="-90"
              :max="90"
              placeholder="纬度"
            ></el-input-number>
          </el-col>
          <el-col :span="6">
            <el-input-number
              v-model="station.longitude"
              :step="0.0001"
              :min="-180"
              :max="180"
              placeholder="经度"
            ></el-input-number>
          </el-col>
          <el-col :span="4">
            <el-input-number
              v-model="station.minElevationAngle"
              :step="1"
              :min="0"
              :max="90"
              placeholder="最小观测角"
            ></el-input-number>
          </el-col>
          <el-col :span="2" style="text-align: right; margin-left: 60px;">
            <el-button @click="removeStation(index)" type="primary">删除</el-button>
          </el-col>
        </el-row>
      </div>

      <!-- 添加地面站 + 提交按钮 -->
      <el-row :gutter="10" style="text-align: center; margin-top: 20px;">
        <el-col :span="12">
          <el-button @click="addStation" type="primary">+ 添加地面站</el-button>
        </el-col>
        <el-col :span="12">
          <el-button type="success" @click="submitForm" :disabled="submitDisabled">
            提交仿真
          </el-button>
        </el-col>
      </el-row>
    </el-form>
  </el-card>

  <!-- 仿真结果与 Cesium 容器 -->
  <el-card>
    <div v-if="!result && !loading" style="color: gray;">
      请上传 TLE 文件并配置地面站以开始仿真。
    </div>
    <div v-if="loading" class="loading-spinner">
      <div class="spinner"></div>
    </div>
    <div id="cesiumContainer"></div>

    <!-- 结果展示 -->
    <div v-if="result" style="margin-top: 40px; border-top: 1px solid #eee; padding-top: 20px;">
      <h3>仿真结果</h3>

      <!-- CSV 下载 -->
      <div v-if="result.csv_files && result.csv_files.length">
        <h4>CSV 报告下载</h4>
        <ul>
          <li v-for="(csv, index) in result.csv_files" :key="index">
            <a
              :href="`http://127.0.0.1:5000/api/download?file=${encodeURIComponent(csv.path)}`"
              :download="csv.filename"
            >
              {{ csv.filename }}
            </a>
          </li>
        </ul>
      </div>

      <!-- AER 图像 -->
      <el-card v-if="result.aer_images && result.aer_images.length" shadow="hover" style="margin-top: 20px;">
        <h4>AER 图像</h4>
        <div v-if="result.aer_images.length > 1" style="display: flex; flex-wrap: wrap; gap: 20px;">
          <div
            v-for="(img, index) in result.aer_images"
            :key="index"
            style="flex: 1; max-width: calc(50% - 10px);"
          >
            <img :src="`data:image/png;base64,${img.base64}`" style="max-width: 100%; height: auto;" />
          </div>
        </div>
        <div v-else v-for="(img, index) in result.aer_images" :key="index">
          <img :src="`data:image/png;base64,${img.base64}`" style="max-width: 100%; margin-bottom: 20px;" />
        </div>
      </el-card>

      <!-- Doppler 图像 -->
      <el-card v-if="result.doppler_images && result.doppler_images.length" shadow="hover" style="margin-top: 20px;">
        <h4>多普勒图像</h4>
        <div v-if="result.doppler_images.length > 1" style="display: flex; flex-wrap: wrap; gap: 20px;">
          <div
            v-for="(img, index) in result.doppler_images"
            :key="index"
            style="flex: 1; max-width: calc(50% - 10px);"
          >
            <img :src="`data:image/png;base64,${img.base64}`" style="max-width: 100%; height: auto;" />
          </div>
        </div>
        <div v-else v-for="(img, index) in result.doppler_images" :key="index">
          <img :src="`data:image/png;base64,${img.base64}`" style="max-width: 100%; margin-bottom: 20px;" />
        </div>
      </el-card>

      <!-- Latency 图像 -->
      <el-card v-if="result.latency_images && result.latency_images.length" shadow="hover" style="margin-top: 20px;">
        <h4>时延图像</h4>
        <div v-if="result.latency_images.length > 1" style="display: flex; flex-wrap: wrap; gap: 20px;">
          <div
            v-for="(img, index) in result.latency_images"
            :key="index"
            style="flex: 1; max-width: calc(50% - 10px);"
          >
            <img :src="`data:image/png;base64,${img.base64}`" style="max-width: 100%; height: auto;" />
          </div>
        </div>
        <div v-else v-for="(img, index) in result.latency_images" :key="index">
          <img :src="`data:image/png;base64,${img.base64}`" style="max-width: 100%; margin-bottom: 20px;" />
        </div>
      </el-card>
    </div>
  </el-card>
</template>

<script setup>
import axios from 'axios'
import { ref, onMounted } from 'vue'
import * as Cesium from 'cesium'
import * as satellite from 'satellite.js'
import '../Widgets/widgets.css'
const tleLines = ref([]); 
const timeRange = ref([]);
const startTimeArray = ref([2024, 1, 1, 0, 0, 0]) // 默认值（可选）
const endTimeArray = ref([2024, 1, 1, 23, 59, 59]) // 默认值
const handleTimeRangeChange = (val) => {
  if (!val || val.length !== 2) {
    console.log('未选择完整的时间范围')
    return
  }
  const [startStr, endStr] = val
  const startDate = new Date(startStr)
  const endDate = new Date(endStr)
  const format = (date) => [
    date.getFullYear(),
    date.getMonth() + 1, // 月份 +1
    date.getDate(),
    date.getHours(),
    date.getMinutes(),
    date.getSeconds()
  ]
  startTimeArray.value = format(startDate)
  endTimeArray.value = format(endDate)
  console.log('更新后的开始时间:', startTimeArray.value)
  console.log('更新后的结束时间:', endTimeArray.value)
}
const selectedSatelliteIndex = ref(null);
Cesium.Ion.defaultAccessToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxYTM3ZWM0Zi04YjMyLTQ5NTktYTY3NC03ODlhOTllMmM4OGIiLCJpZCI6MzIyMzAzLCJpYXQiOjE3NTI3Mzg1MTZ9.s6dWcoPxTs8Q0iKJYf6PJieIaTF6kdsYULfolWEGn-M"
window.CESIUM_BASE_URL = "/"
let viewer=ref(null)
function initSatelliteScene(satellites, groundStations) {
  function getRandomColor() {
    const r = Math.floor(Math.random() * 256);
    const g = Math.floor(Math.random() * 256);
    const b = Math.floor(Math.random() * 256);
    return new Cesium.Color(r / 255.0, g / 255.0, b / 255.0, 1.0); // 返回带透明度的Cesium.Color对象
}
console.log(viewer)
  if (!viewer.value) {
    viewer.value = new Cesium.Viewer("cesiumContainer", {
      infoBox: false,
      geocoder: false,
      homeButton: false,
      sceneModePicker: false,
      baseLayerPicker: false,
      navigationHelpButton: false,
      animation: false,
      timeline: false,
      fullscreenButton: false
    })
    viewer.value.cesiumWidget.creditContainer.style.display = "none"
  } else {
    viewer.value.entities.removeAll()
  }

  // 添加卫星
  const satelliteEntities = []
  satellites.forEach(sat => {
    const satrec = satellite.twoline2satrec(sat.tle1, sat.tle2)
    const positionProperty = new Cesium.SampledPositionProperty()
    const start = Cesium.JulianDate.now()
    const totalSeconds = 5520  // 约92分钟轨道周期
    const color=getRandomColor()
    for (let i = 0; i <= totalSeconds; i += 10) {
      const time = Cesium.JulianDate.addSeconds(start, i, new Cesium.JulianDate())
      const jsDate = Cesium.JulianDate.toDate(time)
      const gmst = satellite.gstime(jsDate)
      const posVel = satellite.propagate(satrec, jsDate)
      if (!posVel.position) continue

      const geo = satellite.eciToGeodetic(posVel.position, gmst)
      const lon = Cesium.Math.toDegrees(geo.longitude)
      const lat = Cesium.Math.toDegrees(geo.latitude)
      const height = geo.height * 1000
      const cart = Cesium.Cartesian3.fromDegrees(lon, lat, height)

      positionProperty.addSample(time, cart)
    }

    const entity = viewer.entities.add({
      name: sat.name,
      position: positionProperty,
      point: { pixelSize: 10, color: color },
      path: {
        show: true,
        leadTime: 0,
        trailTime: 3600 * 24 * 7,
        width: 2,
        material: color
      }
    })

    satelliteEntities.push({ entity, satrec, positionProperty })
  })

  // 添加地面站
  groundStations.forEach(gs => {
    viewer.entities.add({
      name: gs.name,
      position: Cesium.Cartesian3.fromDegrees(gs.longitude, gs.latitude, 0),
      point: { pixelSize: 10, color: getRandomColor() },
      label: {
        text: gs.name,
        font: '14px sans-serif',
        fillColor: getRandomColor(),
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        outlineWidth: 2,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        pixelOffset: new Cesium.Cartesian2(0, -20),
      }
    })
  })

  // 动态链路：计算卫星与地面站的通信链路
  const groundStationPositions = groundStations.map(gs => ({
    name: gs.name,
    position: Cesium.Cartesian3.fromDegrees(gs.longitude, gs.latitude)
  }))

  function calculateElevation(satPos, groundPos) {
    const transform = Cesium.Transforms.eastNorthUpToFixedFrame(groundPos)
    const localPos = Cesium.Matrix4.multiplyByPointAsVector(
      Cesium.Matrix4.inverse(transform, new Cesium.Matrix4()),
      satPos,
      new Cesium.Cartesian3()
    )
    const elevation = Math.atan2(localPos.z, Math.sqrt(localPos.x ** 2 + localPos.y ** 2))
    return Cesium.Math.toDegrees(elevation)
  }

  satelliteEntities.forEach(({ entity, name }) => {
    groundStationPositions.forEach(gs => {
      const groundStationName = gs.name
      const groundStationPosition = gs.position

      const dynamicPositions = new Cesium.CallbackProperty(() => {
        const currentTime = viewer.clock.currentTime
        const satPos = entity.position.getValue(currentTime)

        if (satPos) {
          const elevation = calculateElevation(satPos, groundStationPosition)
          if (elevation > gs.minElevationDeg) {
            return [satPos, groundStationPosition]
          }
        }

        return []
      }, false)

      viewer.entities.add({
        name: `Link: ${name} → ${groundStationName}`,
        polyline: {
          positions: dynamicPositions,
          width: 2,
          material: new Cesium.PolylineGlowMaterialProperty({
            color: Cesium.Color.RED.withAlpha(0.8),
            glowPower: 0.2
          }),
          clampToGround: false
        }
      })
    })
  })

  // 设置时钟
  const start = Cesium.JulianDate.now()
  const totalSeconds = 5520
  const stop = Cesium.JulianDate.addSeconds(start, totalSeconds, new Cesium.JulianDate())

  viewer.clock.startTime = start.clone()
  viewer.clock.stopTime = stop.clone()
  viewer.clock.currentTime = start.clone()
  viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP
  viewer.clock.multiplier = 60
  viewer.clock.shouldAnimate = true
}
// 获取用户名（来自登录页的 sessionStorage）
const username = ref(sessionStorage.getItem('username') || '')

// 页面加载时检查是否已登录
onMounted(() => {
  if (!username.value) {
    alert('请先登录')
    // 假设你使用 Vue Router
    this.$router.push("/login");
  }
})
const tleFile = ref(null)
const tleData = ref([])
const groundStations = ref([
  { name: "", latitude: null, longitude: null, minElevationAngle: null },
])
const result = ref(null) // 用于保存仿真结果
const loading = ref(false)       // 控制结果区域的加载动画
const submitDisabled = ref(false) // 控制按钮是否禁用
function addStation() {
  groundStations.value.push({ name: "", latitude: null, longitude: null, minElevationAngle: null })
}

function removeStation(index) {
  groundStations.value.splice(index, 1)
}
function parseTLEString(tleString) {
  const lines = tleString.split('\n').filter(line => line.trim() !== '');

  const satellites = [];

  for (let i = 0; i < lines.length; i += 3) {
    if (i + 2 >= lines.length) {
      console.warn('TLE 数据不完整，最后一组数据不完整');
      break;
    }
    const name = lines[i].trim();
    const tle1 = lines[i + 1].trim();
    const tle2 = lines[i + 2].trim();
    satellites.push({
      name,
      tle1,
      tle2
    });
  }
  tleLines.value = satellites.map(sat => sat.name);
  console.log(tleLines.value)
  return satellites;
}
function handleFileUpload(event) {
  const file = event.target.files[0]
  if (file && file.name.endsWith('.tle')) {
    tleFile.value = file

    // 使用 FileReader 读取文件内容
    const reader = new FileReader()
    reader.onload = function (e) {
      const content = e.target.result
      tleData.value = parseTLEString(content) // 保存 TLE 文件内容
      console.log('TLE 文件内容：', tleData.value)
    }
    reader.onerror = function (e) {
      alert('读取 TLE 文件失败')
    }
    reader.readAsText(file)
  } else {
    alert('请选择一个 .tle 文件')
  }
}
async function submitForm() {
  if (!tleFile.value) {
    alert('请上传 TLE 文件')
    return
  }
  if (!selectedSatelliteIndex.value) {
    alert('请选择一颗卫星')
    return
  }

  if (!startTimeArray.value || !endTimeArray.value) {
    alert('请设置有效的时间范围')
    return
  }
  initSatelliteScene(tleData.value,groundStations.value)
  loading.value = true
  submitDisabled.value = true
  const formData = new FormData()
  formData.append('tleFile', tleFile.value)
  formData.append('username', username.value)
  formData.append('satelliteIndex', selectedSatelliteIndex.value)
  formData.append('startTime', startTimeArray.value.join(','))
  formData.append('endTime', endTimeArray.value.join(','))
  groundStations.value.forEach((gs, index) => {
    formData.append(`name[]`, gs.name)
    formData.append(`lat[]`, gs.latitude)
    formData.append(`lon[]`, gs.longitude)
    formData.append(`minElev[]`, gs.minElevationAngle)
  })
  console.log('--- FormData 内容 ---')
for (let [key, value] of formData.entries()) {
  console.log(key, ':', value)
}
  
  try {
    const response = await axios.post('http://127.0.0.1:5000/api/sate', formData, {
      headers: { 'Content-Type': 'multipart/form-data' }
    })

    // 保存结果到响应式变量中，触发视图更新
    result.value = response.data
    loading.value = false
    submitDisabled.value = false

  } catch (error) {
    console.error('调用后端失败：', error)
    alert('调用后端失败，请检查网络或服务是否启动')
  }finally{
    loading.value = false
    submitDisabled.value = false
  }
}
</script>

<style scoped>
#cesiumContainer {
  width: 100%;
  height: 60vh;
}
ul {
  list-style-type: none;
  padding-left: 0;
}
li {
  margin-bottom: 10px;
}
a {
  color: #409EFF;
  text-decoration: underline;
}
.loading-spinner {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px;
}

.spinner {
  border: 8px solid #f3f3f3;
  border-top: 8px solid #3498db;
  border-radius: 50%;
  width: 50px;
  height: 50px;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
</style>